home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / DesktopDoubler / Patches / Patches68K.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-26  |  10.6 KB  |  454 lines  |  [TEXT/CWIE]

  1. #define DISABLE_LOCAL_CALLTRACE        1        // Set to 1 to disable Call Traces for this file.
  2. #define DISABLE_LOCAL_DEBUG            0        // Set to 1 to disable all debugging for this file.
  3. #include "DebugUtils.h"
  4.  
  5. #include <Gestalt.h>
  6. #include <Traps.h>
  7. #include <Displays.h>
  8. #include "ContextUtils.h"
  9. #include "Nub.h"
  10. #include "PatchHarness.h"
  11. #include "ProcInfo.h"
  12.  
  13.  
  14.  
  15.  
  16.  
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20.  
  21. enum
  22. {
  23.     _SynchIdleTime                    = 0xABF7
  24. };
  25.  
  26. pascal OSStatus main(PatchDesc **patchList);
  27. static pascal void Install(struct PatchDesc *desc,UniversalProcPtr patch);
  28. static pascal void Remove(struct PatchDesc *desc);
  29. static void DMFinalInitPatchHarness(void);
  30. pascal void DMNotifierPatchHarness(AppleEvent *aevent);
  31. static void SetDMFinalInitTrapAddress(UniversalProcPtr addr);
  32. static void SetDMFinalInitPatchAddress(UniversalProcPtr addr);
  33. static pascal SInt32 DragGrayRgnPatchHarness(RgnHandle rgn,Point start,const Rect *limit,const Rect *slop,SInt16 axis,DragGrayRgnUPP action);
  34. static pascal OSErr GestaltSelectorHarness(OSType selector,SInt32 *response);
  35. static pascal void GetMousePatchHarness(Point *mouseLoc);
  36. static pascal SInt32 MenuSelectPatchHarness(Point *startPt);
  37. static void SetGestaltSelectorResult(SInt32 value);
  38. static void SynchIdleTimePatchHarness(void);
  39. static void SetSynchIdleTimeTrapAddress(UniversalProcPtr addr);
  40. static void SetSynchIdleTimePatchAddress(UniversalProcPtr addr);
  41.  
  42. #ifdef __cplusplus
  43. }
  44. #endif
  45.  
  46.  
  47.  
  48.  
  49.  
  50. PatchDesc                    gDMFinalInitDesc;
  51. DMNotificationProcPtr        gDMNotificationProc = NULL;
  52. PatchDesc                    gDMNotificationDesc;
  53. DragGrayRgnLWProcPtr        gDragGrayRgnTrap = NULL;
  54. DragGrayRgnPatchPtr            gDragGrayRgnPatch = NULL;
  55. PatchDesc                    gDragGrayRgnDesc;
  56. GetMouseProcPtr                gGetMouseTrap = NULL;
  57. GetMousePatchPtr            gGetMousePatch = NULL;
  58. PatchDesc                    gGetMouseDesc;
  59. MenuSelectProcPtr            gMenuSelectTrap = NULL;
  60. MenuSelectPatchPtr            gMenuSelectPatch = NULL;
  61. PatchDesc                    gMenuSelectDesc;
  62. PatchDesc                    gGestaltSelectorDesc;
  63. PatchDesc                    gSynchIdleTimeDesc;
  64.  
  65.  
  66.  
  67.  
  68.  
  69. pascal OSStatus main(PatchDesc **patchList)
  70. {
  71.     GlobalContext        globals;
  72.     PatchDesc            *head = *patchList;
  73.     ProcessSerialNumber    psn;
  74.     OSStatus            err;
  75.     
  76.     
  77.     // Install Gestalt selector.
  78.     gGestaltSelectorDesc.type = 'GSEL';
  79.     gGestaltSelectorDesc.install = Install;
  80.     gGestaltSelectorDesc.remove = Remove;
  81.     gGestaltSelectorDesc.next = head;
  82.     head = &gGestaltSelectorDesc;
  83.     
  84.     err = NewGestalt(kNubSelector,GestaltSelectorHarness);
  85.     if (err != noErr)
  86.     {
  87.         OSType    selector = kNubSelector;
  88.         dprintf(kDConPrefix "NewGestalt('%.4s') failed: %ld\n",&selector,err);
  89.         return err;
  90.     }
  91.     
  92.     // Install _DisplayDispatch(DMFinalInit) patch.
  93.     gDMFinalInitDesc.type = 'DMFI';
  94.     gDMFinalInitDesc.install = Install;
  95.     gDMFinalInitDesc.remove = Remove;
  96.     gDMFinalInitDesc.next = head;
  97.     head = &gDMFinalInitDesc;
  98.     
  99.     SetDMFinalInitTrapAddress(NGetTrapAddress(_DisplayDispatch,ToolTrap));
  100.     NSetTrapAddress((UniversalProcPtr)DMFinalInitPatchHarness,_DisplayDispatch,ToolTrap);
  101.     
  102.     // Install DMNotificationProc.
  103.     gDMNotificationDesc.type = 'DMNt';
  104.     gDMNotificationDesc.install = Install;
  105.     gDMNotificationDesc.remove = Remove;
  106.     gDMNotificationDesc.next = head;
  107.     head = &gDMNotificationDesc;
  108.     
  109.     psn.highLongOfPSN = kNoProcess;
  110.     psn.lowLongOfPSN = kNoProcess;
  111.     err = DMRegisterNotifyProc(DMNotifierPatchHarness,&psn);
  112.     if (err != noErr)
  113.         return err;
  114.     
  115.     // Install _DragGrayRgn patch.
  116.     gDragGrayRgnDesc.type = 'DrgG';
  117.     gDragGrayRgnDesc.install = Install;
  118.     gDragGrayRgnDesc.remove = Remove;
  119.     gDragGrayRgnDesc.next = head;
  120.     head = &gDragGrayRgnDesc;
  121.     
  122.     gDragGrayRgnTrap = (DragGrayRgnLWProcPtr)NGetTrapAddress(_DragGrayRgn,ToolTrap);
  123.     NSetTrapAddress((UniversalProcPtr)DragGrayRgnPatchHarness,_DragGrayRgn,ToolTrap);
  124.     
  125.     // Install _GetMouse patch.
  126.     gGetMouseDesc.type = 'GetM';
  127.     gGetMouseDesc.install = Install;
  128.     gGetMouseDesc.remove = Remove;
  129.     gGetMouseDesc.next = head;
  130.     head = &gGetMouseDesc;
  131.     
  132.     gGetMouseTrap = (GetMouseProcPtr)NGetTrapAddress(_GetMouse,ToolTrap);
  133.     NSetTrapAddress((UniversalProcPtr)GetMousePatchHarness,_GetMouse,ToolTrap);
  134.     
  135.     // Install _MenuSelect patch.
  136.     gMenuSelectDesc.type = 'MenS';
  137.     gMenuSelectDesc.install = Install;
  138.     gMenuSelectDesc.remove = Remove;
  139.     gMenuSelectDesc.next = head;
  140.     head = &gMenuSelectDesc;
  141.     
  142.     gMenuSelectTrap = (MenuSelectProcPtr)NGetTrapAddress(_MenuSelect,ToolTrap);
  143.     NSetTrapAddress((UniversalProcPtr)MenuSelectPatchHarness,_MenuSelect,ToolTrap);
  144.     
  145.     // Install _SynchIdleTime patch.
  146.     gSynchIdleTimeDesc.type = 'IDLE';
  147.     gSynchIdleTimeDesc.install = Install;
  148.     gSynchIdleTimeDesc.remove = Remove;
  149.     gSynchIdleTimeDesc.next = head;
  150.     head = &gSynchIdleTimeDesc;
  151.     
  152.     SetSynchIdleTimeTrapAddress(NGetTrapAddress(_SynchIdleTime,ToolTrap));
  153.     NSetTrapAddress((UniversalProcPtr)SynchIdleTimePatchHarness,_SynchIdleTime,ToolTrap);
  154.     
  155.     // Set patch list.
  156.     *patchList = head;    
  157.     return noErr;
  158. }
  159.  
  160.  
  161.  
  162.  
  163.  
  164. pascal void Install(struct PatchDesc *desc,UniversalProcPtr patch)
  165. {
  166.     GlobalContext    globals;
  167.     
  168.     
  169.     switch(desc->type)
  170.     {
  171.         case 'DMFI':
  172.             SetDMFinalInitPatchAddress((UniversalProcPtr)patch);
  173.             break;
  174.         
  175.         case 'DMNt':
  176.             gDMNotificationProc = (DMNotificationProcPtr)patch;
  177.             break;
  178.         
  179.         case 'DrgG':
  180.             gDragGrayRgnPatch = (DragGrayRgnPatchPtr)patch;
  181.             break;
  182.         
  183.         case 'GetM':
  184.             gGetMousePatch = (GetMousePatchPtr)patch;
  185.             break;
  186.         
  187.         case 'GSEL':
  188.             // Remove Gestalt selector result.
  189.             SetGestaltSelectorResult((SInt32)patch);
  190.             break;
  191.         
  192.         case 'MenS':
  193.             gMenuSelectPatch = (MenuSelectPatchPtr)patch;
  194.             break;
  195.         
  196.         case 'IDLE':
  197.             SetSynchIdleTimePatchAddress((UniversalProcPtr)patch);
  198.             break;
  199.         
  200.         default:
  201.             dprintf(kDConPrefix "Install: patch '%.4s' not found\n",&desc->type);
  202.             break;
  203.     }
  204. }
  205.  
  206.  
  207.  
  208.  
  209.  
  210. pascal void Remove(struct PatchDesc *desc)
  211. {
  212.     GlobalContext    globals;
  213.     
  214.     
  215.     switch(desc->type)
  216.     {
  217.         case 'DMFI':
  218.             SetDMFinalInitPatchAddress((UniversalProcPtr)NULL);
  219.             break;
  220.         
  221.         case 'DMNt':
  222.             gDMNotificationProc = (DMNotificationProcPtr)NULL;
  223.             break;
  224.         
  225.         case 'DrgG':
  226.             gDragGrayRgnPatch = (DragGrayRgnPatchPtr)NULL;
  227.             break;
  228.         
  229.         case 'GetM':
  230.             gGetMousePatch = (GetMousePatchPtr)NULL;
  231.             break;
  232.         
  233.         case 'GSEL':
  234.             // Remove Gestalt selector result.
  235.             SetGestaltSelectorResult((SInt32)0);
  236.             break;
  237.         
  238.         case 'MenS':
  239.             gMenuSelectPatch = (MenuSelectPatchPtr)NULL;
  240.             break;
  241.         
  242.         case 'IDLE':
  243.             SetSynchIdleTimePatchAddress((UniversalProcPtr)NULL);
  244.             break;
  245.         
  246.         default:
  247.             dprintf(kDConPrefix "Remove: patch '%.4s' not found\n",&desc->type);
  248.             break;
  249.     }
  250. }
  251.  
  252.  
  253.  
  254.  
  255.  
  256. asm void DMFinalInitPatchHarness(void)
  257. {
  258.     MOVEA.L        @PatchAddressStorage,A0        // Put address of patch into A0.
  259.     CMPA.W        #0x0000,A0                    // Compare address of patch to NULL.
  260.     BEQ.S        @CallRealTrap                // Goto @CallRealTrap if was NULL.
  261.     CMPI.W        #0x01ED,D0                    // Check for targetted selector.
  262.     BNE.S        @CallRealTrap                // Goto @CallRealTrap if was NULL.
  263.     
  264.     SUBA.W        #4,SP                        // Call it so we can tail patch
  265.     MOVE.L        D0,-(SP)
  266.     MOVE.W        12(SP),D0
  267.     MOVE.W        D0,4(SP)
  268.     MOVE.L        (SP)+,D0
  269.     MOVEA.L        @TrapAddressStorage,A0        // Put address of trap in A0.
  270.     JSR            (A0)
  271.     ADDA.W        #2,SP
  272.     MOVE.L        (SP)+,D0
  273.     ADDA.W        #2,SP
  274.     CLR.W        (SP)
  275.     MOVEM.L        A0-A1/D0-D2,-(SP)            // Save CPU state on stack.
  276.     MOVEA.L        @PatchAddressStorage,A0        // Put address of patch into A0.
  277.     JSR            (A0)                        // Call patch code.
  278.     MOVEM.L        (SP)+,A0-A1/D0-D2            // Restore CPU state from stack.
  279.     MOVE.L        D0,-(SP)
  280.     RTS
  281.     
  282. @CallRealTrap:
  283.     MOVE.L        @TrapAddressStorage,-(SP)    // Put address of trap in the stack.
  284.     RTS                                        // Directly RTS back to real trap.
  285.     
  286. entry static SetDMFinalInitTrapAddress
  287.     LEA            @TrapAddressStorage,A0
  288.     MOVE.L        4(SP),(A0)
  289.     RTS
  290.     
  291. entry static SetDMFinalInitPatchAddress
  292.     LEA            @PatchAddressStorage,A0
  293.     MOVE.L        4(SP),(A0)
  294.     RTS
  295.     
  296. @TrapAddressStorage:
  297.     DC.L        0x00000000                    // Storage for trap address.
  298. @PatchAddressStorage:
  299.     DC.L        0x00000000                    // Storage for patch address.
  300. }
  301.  
  302.  
  303.  
  304.  
  305.  
  306. pascal void DMNotifierPatchHarness(AppleEvent *aevent)
  307. {
  308.     GlobalContext    globals;
  309.     
  310.     if (gDMNotificationProc != NULL)
  311.         CallDMNotificationProc(gDMNotificationProc,aevent);
  312. }
  313.  
  314.  
  315.  
  316.  
  317.  
  318. pascal SInt32 DragGrayRgnPatchHarness(RgnHandle rgn,Point start,const Rect *limit,const Rect *slop,SInt16 axis,DragGrayRgnUPP action)
  319. {
  320.     DragGrayRgnLWProcPtr    dragGrayRgnTrap;
  321.     DragGrayRgnPatchPtr        dragGrayRgnPatch;
  322.     SInt32                    result;
  323.     
  324.     
  325.     {
  326.         GlobalContext    globals;
  327.         
  328.         dragGrayRgnTrap = gDragGrayRgnTrap;
  329.         dragGrayRgnPatch = gDragGrayRgnPatch;
  330.     }
  331.     
  332.     // Call patch, if installed.
  333.     if (dragGrayRgnPatch != NULL)
  334.         result = CallDragGrayRgnPatch(dragGrayRgnPatch,rgn,start,limit,slop,axis,action,dragGrayRgnTrap);
  335.     else
  336.     {
  337.         // Call real DragGrayRgn.
  338.         result = CallDragGrayRgnLWProc(dragGrayRgnTrap,rgn,start,limit,slop,axis,action);
  339.     }
  340.     
  341.     return result;
  342. }
  343.  
  344.  
  345.  
  346.  
  347.  
  348. asm pascal OSErr GestaltSelectorHarness(OSType selector,SInt32 *response)
  349. {
  350.     MOVEA.L        4(SP),A0                // Move response into A0.
  351.     MOVE.L        @ResultStorage,(A0)        // Move *ResultStorage into *response.
  352.     CLR.W        12(SP)                    // Set the return value to no error.
  353.     RTD            #8                        // Clean up pascal stack frame and return.
  354.     
  355. entry static SetGestaltSelectorResult
  356.     LEA            @ResultStorage,A0
  357.     MOVE.L        4(SP),(A0)
  358.     RTS
  359.     
  360. @ResultStorage:
  361.     DC.L        0x00000000                // 4 Byte return value.
  362. }
  363.  
  364.  
  365.  
  366.  
  367.  
  368. pascal void GetMousePatchHarness(Point *mouseLoc)
  369. {
  370.     GetMouseProcPtr        getMouseTrap;
  371.     GetMousePatchPtr    getMousePatch;
  372.     
  373.     
  374.     {
  375.         GlobalContext    globals;
  376.         
  377.         getMouseTrap = gGetMouseTrap;
  378.         getMousePatch = gGetMousePatch;
  379.     }
  380.     
  381.     // Call patch, if installed.
  382.     if (getMousePatch != NULL)
  383.         CallGetMousePatch(getMousePatch,mouseLoc,getMouseTrap);
  384.     else
  385.     {
  386.         // Call real GetMouse.
  387.         CallGetMouseProc(getMouseTrap,mouseLoc);
  388.     }
  389. }
  390.  
  391.  
  392.  
  393.  
  394.  
  395. pascal SInt32 MenuSelectPatchHarness(Point *startPt)
  396. {
  397.     MenuSelectProcPtr    menuSelectTrap;
  398.     MenuSelectPatchPtr    menuSelectPatch;
  399.     SInt32                result;
  400.     
  401.     
  402.     {
  403.         GlobalContext    globals;
  404.         
  405.         menuSelectTrap = gMenuSelectTrap;
  406.         menuSelectPatch = gMenuSelectPatch;
  407.     }
  408.     
  409.     // Call patch, if installed.
  410.     if (menuSelectPatch != NULL)
  411.         result = CallMenuSelectPatch(menuSelectPatch,startPt,menuSelectTrap);
  412.     else
  413.     {
  414.         // Call real MenuSelect.
  415.         result = CallMenuSelectProc(menuSelectTrap,startPt);
  416.     }
  417.     
  418.     return result;
  419. }
  420.  
  421.  
  422.  
  423.  
  424.  
  425. asm void SynchIdleTimePatchHarness(void)
  426. {
  427.     MOVEA.L        @TrapAddressStorage,A1        // Put address of trap into A1.
  428.     MOVEA.L        @PatchAddressStorage,A0        // Put address of patch into A0.
  429.     CMPA.W        #0x0000,A0                    // Compare address of patch to NULL.
  430.     BEQ.S        @CallRealTrap                // Goto @CallRealTrap if was NULL.
  431.     
  432.     MOVEM.L        D3-D7/A1-A6,-(A7)            // Save CPU state on stack.
  433.     JSR            (A0)                        // Call patch code.
  434.     MOVEM.L        (A7)+,D3-D7/A1-A6            // Restore CPU state from stack.
  435.     
  436. @CallRealTrap:
  437.     JMP            (A1)                        // Directly jump to real trap.
  438.     
  439. entry static SetSynchIdleTimeTrapAddress
  440.     LEA            @TrapAddressStorage,A0
  441.     MOVE.L        4(SP),(A0)
  442.     RTS
  443.     
  444. entry static SetSynchIdleTimePatchAddress
  445.     LEA            @PatchAddressStorage,A0
  446.     MOVE.L        4(SP),(A0)
  447.     RTS
  448.     
  449. @TrapAddressStorage:
  450.     DC.L        0x00000000                    // Storage for trap address.
  451. @PatchAddressStorage:
  452.     DC.L        0x00000000                    // Storage for patch address.
  453. }
  454.